﻿using HtmlAgilityPack;
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Xml;
using UpdateDesktopDocHtmlContent.JSFileMatch;
using UpdateDesktopDocHtmlContent.NetIPChange;
using UpdateDesktopDocHtmlContent.Properties;

namespace UpdateDesktopDocHtmlContent
{
    public partial class Form1 : Form
    {
        private string m_lastSelectedDirectory = null;

        public string LastSelectedDirectory { get => m_lastSelectedDirectory; set => m_lastSelectedDirectory = value; }
        public bool IsSelience { get; set; }
        System.Windows.Forms.Timer timer;

        #region 获得存储目录
        
        private string ContentDir
        {
            get
            {
                return Path.Combine(GlobalConfig.DataFile, "content_" + this.comboBox1.SelectedItem.ToString());
            }
        }
        #endregion

        public Form1()
        {
            InitializeComponent();
        }
        public void Form1_Load(object sender, EventArgs e)
        {
            LoadConfig();
            /* timer = new Timer();
             timer.Interval = 3000;
             timer.Tick += Timer_Tick;
             //timer.Start();*/

            this.comboBox1.SelectedIndex = 0;

            this.FormClosing += Form1_FormClosing;
        }

        #region 系统IP配置
        private void LoadConfig()
        {
            /*var iniFile = Path.Combine(DataFile, "config.ini");
            if (File.Exists(iniFile) == false)
            {
                MessageBox.Show("你需要在" + iniFile + "创建这个文件，里面写WebSocket的地址");
                return;
            }
            var t = File.ReadAllLines(iniFile);
            if (t != null && t.Length > 0)
            {
                this.textBox1.Text = t[0];
            }
            if (t != null && t.Length > 1)
            {
                this.textBoxNGUrl.Text = t[1];
            }*/

            this.textBox1.Text = GlobalConfig.Instance.WebsocketIp;
            this.textBoxNGUrl.Text = GlobalConfig.Instance.NginxIP;
        }
        private void button4_Click(object sender, EventArgs e)
        {
            GlobalConfig.Instance.WebsocketIp = this.textBox1.Text;
            GlobalConfig.Instance.NginxIP = this.textBoxNGUrl.Text;
            GlobalConfig.Instance.Save();
            MessageBox.Show("OK");
        }


        private string m_mdStyleStr;
        private string m_cimPaparSaveDataStr;
        private string m_editMdNetStr;
        private string m_cimPaperEditorHTMLStr;
        private string GetMyStyleText(string appName)
        {
            m_mdStyleStr = UpdateDesktopDocHtmlContent.Properties.Resources.mdStyle;

            var wsUrl = this.textBox1.Text.Trim().TrimEnd(new char[] { '/' });
            var ngUrl = this.textBoxNGUrl.Text.Trim().TrimEnd(new char[] { '/' });


            m_mdStyleStr = m_mdStyleStr.Replace("{WSURL}", wsUrl);
            m_mdStyleStr = Regex.Replace(m_mdStyleStr,"{NGURL}", ngUrl);
            m_mdStyleStr = m_mdStyleStr.Replace("{APPNAME}", appName);

            m_cimPaparSaveDataStr = Resources.saveData;
            m_cimPaparSaveDataStr= Regex.Replace(m_cimPaparSaveDataStr, "{WSURL}", wsUrl);
            m_cimPaparSaveDataStr = Regex.Replace(m_cimPaparSaveDataStr, "{NGURL}", ngUrl);

            m_editMdNetStr = Resources.editMd_net;
            m_editMdNetStr = Regex.Replace(m_editMdNetStr, "{WSURL}", wsUrl);
            m_editMdNetStr = Regex.Replace(m_editMdNetStr, "{NGURL}", ngUrl);

            m_cimPaperEditorHTMLStr=Resources.cimPaperEditorHTML;
            m_cimPaperEditorHTMLStr = Regex.Replace(m_cimPaperEditorHTMLStr, "{NGURL}", ngUrl);
            return m_mdStyleStr;
        }
        #endregion

        private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {
            if (timer != null) { timer.Stop(); }
        }

        private static bool m_isPrcessing = false;
        private static void Timer_Tick(object sender, EventArgs e)
        {
            var fs = "D:\\Program Files\\SendMailServer\\t.txt";
            if (m_isPrcessing==false&&File.Exists(fs))
            {
                m_isPrcessing=true;
                File.Delete(fs);
                StreamWriter streamWriter = File.CreateText("D:\\Program Files\\SendMailServer\\log.txt");
                streamWriter.WriteLine("Aoto Git"); streamWriter.Flush();
                List<string> codes = new List<string>();
                codes.Add("D:");
                string gitDir = "D:\\Program Files\\SendMailServer1.3\\DesktopDocGit\\";
                string nginxDesckopDir = "D:\\nginx-1.16.1\\html\\desktopDoc\\";
                string docDic = gitDir + "agcim-desktop.doc\\";
                string distDir = docDic+"docs\\.vuepress\\dist";
                codes.Add("cd "+ gitDir);
                codes.Add("git clone http://augur.gitlab/master/agcim/agcim-desktop/agcim-desktop.doc.git");
                codes.Add("git pull");
                codes.Add("rd /s/q "+ distDir);
                codes.Add("cd " + docDic);
                codes.Add("npm run build");
                
                codes.Add("rd /s/q "+ nginxDesckopDir);
                codes.Add("xcopy /e /y /q "+distDir +" "+ nginxDesckopDir);
                codes.Add("exit");


                Program.RunGit("", codes, streamWriter);

                //Program.RunDownloadGit("D:\\Program Files\\SendMailServer1.3\\Debug\\UpdateDesktopDocHtmlContent_更新代码&更新到nginx服务.bat", streamWriter);
                streamWriter.Dispose();
                streamWriter.Close();


                m_isPrcessing = false;
            }
        }

        private void button1_Click(object sender, EventArgs e)
        {
            FolderSelectDialog dlg = new FolderSelectDialog();
            dlg.Title = "选择知识网";
            if (dlg.ShowDialog())
            {
                LastSelectedDirectory = dlg.FileName;
                ProcessDirectory();
                SaveJiKeFiles();
                SaveMdEditor();
            }
        }
        private void button2_Click(object sender, EventArgs e)
        {
            if (LastSelectedDirectory == null)
            {
                button1_Click(null, null);
            }
            else
            {
                ProcessDirectory();
            }
        }
        public void ProcessDirectory()
        {
            var appName = this.comboBox1.SelectedItem.ToString();
            GetMyStyleText(appName);

            var isOnlyCheckMdStyleFile = this.checkBox2.Checked;

            if (Directory.Exists(ContentDir) == false)
            {
                Directory.CreateDirectory(ContentDir);
            }
            //如果不是仅更新mdStyle文档，则删除文件夹重建
            if (isOnlyCheckMdStyleFile == false)
            {
                Directory.Delete(ContentDir, true);
                if (Directory.Exists(ContentDir) == false)
                {
                    Directory.CreateDirectory(ContentDir);
                }
            }
            

            var isUpdateAppJS = this.checkBox_processAppJS.Checked;
            if (isUpdateAppJS)
            {
                FindAppJs(LastSelectedDirectory);
            }
            
            if (isOnlyCheckMdStyleFile)
            {
                UpdateMdFile(LastSelectedDirectory);
                if (IsSelience == false)
                    MessageBox.Show("更新mdStyle.OK");
                return;
            }
            if (this.checkBox_moveImgForAI.Checked)
            {
                MoveImgsForAI moveImgsForAI = new MoveImgsForAI();
                moveImgsForAI.MoveImages(appName,LastSelectedDirectory);
            }

            if (checkBoxCreateMinPng.Checked)
            {
                ResizedImageHelper resizedImageHelper = new ResizedImageHelper(LastSelectedDirectory);
                resizedImageHelper.OnImageProcess += ResizedImageHelper_OnImageProcess;
                Thread thread = new Thread(resizedImageHelper.ProcessDirectory);
                thread.Start();
            }

            var notProcessHtmlContent = this.checkBox4.Checked;
            if (notProcessHtmlContent)
            {
                if (IsSelience == false)
                    MessageBox.Show("结束 OK");
                return;
            }

            ProductFuncMatch.Start();
            ProductFuncMatch.SetConfig(this.textBoxNGUrl.Text);
            ProductFuncMatch.ProcessFiles(LastSelectedDirectory);

            JSFileMatchHelper jSFileMatchHelper = new JSFileMatchHelper()
            {
                ContentDir = ContentDir,
                m_mdStyleStr = m_mdStyleStr,
                NGUrl = this.textBoxNGUrl.Text.Trim().TrimEnd(new char[] { '/' })
            };
            jSFileMatchHelper.ProcessFile(LastSelectedDirectory); 

            CreateIndexSearchFiles();
            if (IsSelience == false)
                MessageBox.Show("OK");
        }

        private void ResizedImageHelper_OnImageProcess(object sender, EventArgs e)
        {
            if (this.InvokeRequired == false)
            {
                var dlg = new EventHandler(ResizedImageHelper_OnImageProcess);
                this.Invoke(dlg, new object[] { sender,e });   
            }
            else
            {
                this.progressBar1.Value = (sender as ResizedImageHelper).CurrentImageIndex * 100 / (sender as ResizedImageHelper).ImageCount;
            }
        }

        #region 更新MdStyle文件
        private void UpdateMdFile(string dir)
        {
            var dirs = new DirectoryInfo(dir).GetDirectories();
            for (var i = 0; i < dirs.Length; i++)
            {
                var mdStyleJS1 = Path.Combine(dirs[i].FullName, "mdStyle.js");
                File.WriteAllText(mdStyleJS1, m_mdStyleStr);
                var childrenDirs= dirs[i].GetDirectories();
                if(childrenDirs.Length > 0)
                {
                    UpdateMdFile(dirs[i].FullName);
                }
            }
            var mdStyleJS3 = Path.Combine(dir, "mdStyle.js");
            File.WriteAllText(mdStyleJS3, m_mdStyleStr);
        } 
        #endregion


        private void FindAppJs(string path)
        {
            var fs = new DirectoryInfo(path).GetFiles("app.*.js", SearchOption.AllDirectories);
            for(var i = 0; i < fs.Length; i++)
            {
                FindAppJs(fs[i]);
            }
        }
        private void FindAppJs(FileInfo file)
        {
            var lines = File.ReadAllText(file.FullName);
            var t = lines.IndexOf("prototype.confirmTransition");
            if (t > 0)
            {
                var t2 = lines.IndexOf("(", t);
                var t3 = lines.IndexOf(")", t2);
                var t4 = lines.IndexOf("{", t3);
                var paramStrs = lines.Substring(t2 + 1, t3 - t2 - 1).Split(',');
                var s1 = lines.Substring(t4);

                var fii = SendFileRequset(paramStrs[0]);
                if (lines.IndexOf(fii) < 0)
                {
                    var s4 = lines.Substring(0, t4 + 1);
                    var s5 = lines.Substring(t4 + 1);
                    lines = s4 + "\r\n" + fii + "\r\n" + s5;
                }
                else
                {
                    t = 0;
                }
            }
            var ok2 = FindAppJS_JSFileMatch(ref lines);
            if (ok2)
            {
                if (IsSelience == false)
                    MessageBox.Show("JSFileMatch OK");
            }
            if (t > 0 || ok2)
            {
                File.WriteAllText(file.FullName, lines);
            }
        }
        private bool FindAppJS_JSFileMatch(ref string lines)
        {
            var t = lines.IndexOf("assets/js/");if (t < 0) return false;
            var t1 = lines.IndexOf(':', t); if (t1 < 0) return false;
            var t2 = lines.LastIndexOf('{', t1); if (t2 < 0) return false;
            var t3 = lines.IndexOf('}', t2); if (t3 < 0) return false;
            var innerJSMatch = lines.Substring(t2, t3 - t2 + 1);
            var f1 = lines.Substring(0, t2);
            var f2 = lines.Substring(t3 + 1);
            lines = f1 + "window.jsFileMatch" + f2;

            var contentDir = Path.Combine(ContentDir, "jsFileMatch.txt");
            File.WriteAllText(contentDir, innerJSMatch);
            return true;
        }
        private string SendFileRequset(string p1)
        {
            string s = "getContentByUrl("+p1+".redirectedFrom);";
            return s;
        }

        #region 3.处理极客
        private void SaveJiKeFiles()
        {
            var dir = Path.Combine(LastSelectedDirectory, "jike");
            if (Directory.Exists(dir))
            {
                var fs = Resources.cimPaperEditor;
                var zipFile = Path.Combine(dir, "cimPaperEditor.zip");
                File.WriteAllBytes(zipFile, fs);
                ExtractFile(zipFile, dir);
                File.Delete(zipFile);
            }

            UpdatePaparSaveDataFile();
        }
        private void UpdatePaparSaveDataFile()
        {
            var dir = Path.Combine(LastSelectedDirectory, "jike");
            var mdStyleJS3 = Path.Combine(dir, "assets/scripts/saveData.js");
            File.WriteAllText(mdStyleJS3, m_cimPaparSaveDataStr);
        }
        // 解压文件方法
        public void ExtractFile(string zipFile, string extractPath)
        {
            if (File.Exists(zipFile) == false)
            {
                return;
            }
            // 打开zip文件
            using (ZipArchive archive = ZipFile.OpenRead(zipFile))
            {
                // 遍历zip文件中的每个文件
                foreach (ZipArchiveEntry entry in archive.Entries)
                {
                    // 创建文件保存路径
                    string fullPath = Path.Combine(extractPath, entry.FullName);

                    // 创建文件夹
                    if (entry.FullName.EndsWith("/"))
                    {
                        Directory.CreateDirectory(fullPath);
                        continue;
                    }
                    var dir = Path.GetDirectoryName(fullPath);
                    if (Directory.Exists(dir) == false)
                    {
                        Directory.CreateDirectory(dir);
                    }
                    // 创建文件流
                    using (FileStream fileStream = new FileStream(fullPath, FileMode.Create))
                    {
                        // 复制zip文件的流到文件流中
                        using (Stream stream = entry.Open())
                        {
                            stream.CopyTo(fileStream);
                        }
                    }
                }
            }
        }
        #endregion

        #region 4.处理md的编辑
        private void SaveMdEditor()
        {
            var dir = Path.Combine(LastSelectedDirectory, "jike");
            if (Directory.Exists(dir))
            {
                CopyMdEditorFile(Resources.editMd, "editMd.html");
                CopyMdEditorFile(m_editMdNetStr, "editMd-net.js");
                CopyMdEditorFile(Resources.editMd_purify_min, "editMd-purify.min.js");
                CopyMdEditorFile(Resources.editMd_marked_min, "editMd-marked.min.js");
                CopyMdEditorFile(m_cimPaperEditorHTMLStr, "cimPaperEditor.html");

                CopyMdEditorFile(Resources.chatWithCIMMachine, "chatWithCIMMachine.html");
                CopyMdEditorFile(Resources.chatJS, "chatJS.js");
                CopyMdEditorFile(Resources.mobilecheck, "mobilecheck.js");
                CopyMdEditorAssetCssFile(Resources.mobileCSS, "mobile.css");
                CopyMdEditorAssetCssFile(Resources.chatJS, "chatJS.css");
            }
        }
        private void CopyMdEditorFile(string fileContent,string fileName)
        {
            var dir = Path.Combine(LastSelectedDirectory, "jike");
            var mdStyleJS3 = Path.Combine(dir, fileName);
            File.WriteAllText(mdStyleJS3, fileContent);
        }
        private void CopyMdEditorAssetCssFile(string fileContent, string fileName)
        {
            var dir = Path.Combine(LastSelectedDirectory, "jike");
            dir = Path.Combine(dir, "assets");
            dir = Path.Combine(dir, "styles");
            var mdStyleJS3 = Path.Combine(dir, fileName);
            File.WriteAllText(mdStyleJS3, fileContent);
        }
        #endregion

        #region 创建索引文件
        private void CreateIndexSearchFiles()
        {
            var files = new DirectoryInfo(ContentDir).GetFiles("*.txt", SearchOption.AllDirectories);
            var str = File.CreateText(Path.Combine(ContentDir,"IndexSearch.txt"));
            var t1 = System.Environment.TickCount;

            List<string> filterString = new List<string>();
            filterString.Add("&quot");
            filterString.Add("&lt");
            filterString.Add("&gt");

            List<string> imgStrings = new List<string>();
            imgStrings.Add("iVBORw0");
            imgStrings.Add("image/png;");

            for (var j = 0; j < files.Length; j++)
            {
                var file = files[j];
                if (file.Name == "jsFileMatch.txt")
                {
                    continue;
                }
                if (file.Name == "fileMatch.txt")
                {
                    continue;
                }

                HtmlAgilityPack.HtmlDocument document = new HtmlAgilityPack.HtmlDocument();
                document.LoadHtml(File.ReadAllText(file.FullName));

                ClearCodes(document);

                var fileName = GetFileName(document);
                if (fileName == null)
                {
                    continue;
                }
                str.WriteLine("<ContentFile>" + fileName+"&"+Path.GetFileNameWithoutExtension(file.Name) + "</ContentFile>");
                var iterText = document.DocumentNode.InnerText;
                for (var i = 0; i < imgStrings.Count; i++)
                {
                    while (true)
                    {
                        var t = iterText.IndexOf(imgStrings[i]);
                        if (t == -1)
                        {
                            break;
                        }
                        var t23 = iterText.IndexOf(';', t + 20);
                        var bs = iterText.Substring(0, t);
                        var bs2 = iterText.Substring(t23 + 1);
                        iterText = bs + bs2;
                    }
                }

                for (var i = 0; i < filterString.Count; i++)
                {
                    iterText = Regex.Replace(iterText, filterString[i], "");
                }
                str.WriteLine(iterText);
                str.Flush();
            }
            str.Flush();
            str.Close();
            var t2 = System.Environment.TickCount;
            MessageBox.Show("完成 文件索引 ," + (t2 - t1));
        }

        private void ClearCodes(HtmlAgilityPack.HtmlDocument document)
        {
            for (var i = 0; i < document.DocumentNode.ChildNodes.Count; i++)
            {
                ClearCodes(document.DocumentNode.ChildNodes[i]);
            }
            for (var k = document.DocumentNode.ChildNodes.Count - 1; k >= 0; k--)
            {
                if (document.DocumentNode.ChildNodes[k].HasClass("page-nav"))
                {
                    document.DocumentNode.RemoveChild(document.DocumentNode.ChildNodes[k]);
                    break;
                }
            }
        }
        private void ClearCodes(HtmlNode htmlNode)
        {
            for (var i = htmlNode.ChildNodes.Count - 1; i >= 0; i--)
            {
                var ht = htmlNode.ChildNodes[i].OuterHtml;
                var t = ht.IndexOf("line-numbers-mode");
                if (t < 40 && t > 0)
                {
                    htmlNode.ChildNodes.Remove(i);
                    continue;
                }
                if (ht.Contains("line-numbers-mode"))
                {
                    ClearCodes(htmlNode.ChildNodes[i]);
                }
            }
        }

        private string GetFileName(HtmlAgilityPack.HtmlDocument document)
        {
            var txt = document.DocumentNode.OuterHtml;
            var t1 = txt.IndexOf("<h1");
            if (t1 < 0)
            {
                return null;
            }
            var t2 = txt.IndexOf("</h1>");
            var innTxt = txt.Substring(t1, t2 - t1);
            var t3 = innTxt.IndexOf("id");
            var t4 = innTxt.IndexOf("\"", t3 + 2);
            var t5 = innTxt.IndexOf("\"", t4 + 2);
            var innTxt2 = innTxt.Substring(t4 + 1, t5 - t4 - 1);
            return innTxt2;
        }
        #endregion

        #region 修改地址
        private void button3_Click_1(object sender, EventArgs e)
        {
            NetIPChangeForm form = new NetIPChangeForm();
            form.ShowDialog();
        }
        #endregion

        
    }
}
